#include "Mapion.h"
#include <QObject>
#include <QMap>
#include <QSet>
#include "../XXqtDefine.h"

#include <functional>
#include <mutex>
#include <QMetaProperty>
#include "XXlogger.h"

template<class T>
T Mapion::fromVariantMap(const QVariantMap &map){
    T obj(map);
    return obj;
}
template<class T>
QList<T> Mapion::fromVariantMaps(const QList<QVariantMap> &maps){
    QList<T> objs;
    for (auto iter=maps.begin(); iter!=maps.end(); iter++) {
        T obj;
        obj.fromMap(*iter);
        objs << obj;
    }
    return objs;
}
QList<QVariantMap> Mapion::toVariantMaps(const QList<Mapion> &mapions){
    QList<QVariantMap> maps;
    for (auto iter=mapions.begin(); iter!=mapions.end(); iter++) {
        maps << iter->toMap();
    }
    return maps;
}

Mapion::Mapion(QObject *parent)
    :QObject (parent){
}
Mapion::Mapion(const Mapion &obj)
    :QObject (){
    *this = obj;
}
Mapion::Mapion(const QVariantMap &map)
    :QObject (){
    fromMap(map);
}

#include <QDebug>
QVariantMap Mapion::toMap() const{
    QVariantMap map;

    const QMetaObject *mobj = this->metaObject();
    int count = mobj->propertyCount();
    for (int index=0; index<count; index++) {
        QMetaProperty property = mobj->property(index);
        if(!property.isUser()){
            continue;
        }
        map[property.name()] = property.read(this);
    }

    return map;
}
void Mapion::fromMap(const QVariantMap &map){
    const QMetaObject *mobj = this->metaObject();
    int count = mobj->propertyCount();
    for (int index=0; index<count; index++) {
        QMetaProperty property = mobj->property(index);
        if(!property.isUser() || !map.contains(property.name())){
            continue;
        }
        setProperty(property.name(),map[property.name()]);
    }
}
void Mapion::operator=(const Mapion &obj){   
    auto theOtherProperyNames = obj.dynamicPropertyNames();
    const QMetaObject *mobj = this->metaObject();
    int count = mobj->propertyCount();

    for (int index=0; index<count; index++) {
        QMetaProperty property = mobj->property(index);
        if(!property.isUser()){
            continue;
        }
        setProperty(property.name(),obj.property(property.name()));
    }
}
